﻿using System;
using System.Collections.Generic;

namespace Simp.CodeModel.CoreFunctions.Sequences
{
	/// <summary>Encapsulates a function forcing the evaluation of a sequence into an explicit form.</summary>
	public class ListFunction : IFunction
	{
		private static readonly string[] PARAMETER_NAMES = new[] { "sequence" };

		#region IFunction Members
		string IFunction.FunctionName
		{
			get { return "List"; }
		}

		string[] IFunction.ParameterNames
		{
			get { return PARAMETER_NAMES; }
		}

		IFunctionParameterBinding[] IFunction.DefaultParameterValues
		{
			get { return FunctionHelper.EmptyBindings; }
		}

		IFunction IFunction.Simplify(SimplificationMode simplificationMode, params IFunction[] parameters)
		{
			FunctionHelper.ValidateParameters(this, parameters);

			BoundFunctionCalling boundFunctionCalling = parameters[0] as BoundFunctionCalling;

			if (boundFunctionCalling == null)
			{
				return null;
			}
			else
			{
				ExplicitSequenceFunction explicitSequence = boundFunctionCalling.InnerFunction as ExplicitSequenceFunction;

				if (explicitSequence != null)
				{	//	Function call is no longer necessary, the underlying sequence already is an explicit sequence
					return boundFunctionCalling;
				}
				else
				{
					ISequenceAccessor accessor = FunctionHelper.GetAccessor(boundFunctionCalling);

					if (accessor == null)
					{
						return null;
					}
					else
					{
						List<IFunction> functionList = new List<IFunction>(new SyncSimplifyingSequenceAccessor(accessor));

						return new BoundFunctionCalling(new ExplicitSequenceFunction(functionList.Count), functionList.ToArray());
					}
				}
			}
		}

		IFunction IFunction.AcceptVisitor(IFunctionVisitor visitor)
		{
			return null;
		}
		#endregion
	}
}